home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume25 / QBATCH / part02 < prev    next >
Encoding:
Text File  |  1991-11-04  |  55.8 KB  |  1,805 lines

  1. Newsgroups: comp.sources.misc
  2. From: alan@tharr.UUCP (Alan Saunders)
  3. Subject:  v25i021:  QBATCH - a queued batch processing system for UNIX, Part02/06
  4. Message-ID: <1991Nov5.034628.4930@sparky.imd.sterling.com>
  5. X-Md4-Signature: 0646577a1904b6ae9e177e210480e597
  6. Date: Tue, 5 Nov 1991 03:46:28 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: alan@tharr.UUCP (Alan Saunders)
  10. Posting-number: Volume 25, Issue 21
  11. Archive-name: QBATCH/part02
  12. Environment: UNIX
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then unpack
  16. # it by saving it into a file and typing "sh file".  To overwrite existing
  17. # files, type "sh file -c".  You can also feed this as standard input via
  18. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  19. # will see the following message at the end:
  20. #        "End of archive 2 (of 6)."
  21. # Contents:  NOTICE doc/chap.01 doc/chap.03 doc/glossary man/js.l
  22. #   man/qf.l man/qt.l man/queue.l src/jm.c src/jn.c src/qbatch.h
  23. #   src/qs.c src/qt.c src/time.c
  24. # Wrapped by root@vfib_d on Thu Oct 31 15:46:39 1991
  25. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  26. if test -f 'NOTICE' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'NOTICE'\"
  28. else
  29. echo shar: Extracting \"'NOTICE'\" \(3179 characters\)
  30. sed "s/^X//" >'NOTICE' <<'END_OF_FILE'
  31. X                QBATCH .. a queued batch processing system for UNIX
  32. X
  33. Disclaimer
  34. X
  35. X     The QBATCH system and its related programs were
  36. X     written by Alan D. Saunders and are
  37. X     Copyright (c) Vita Services Ltd. 1990 and
  38. X     Copyright (c) Vita Fibres Ltd. 1991
  39. X
  40. QBATCH is distributed free of charge in the hope that you may be able to
  41. make some use of it. It is however distributed  AS IS, WITHOUT ANY WARRANTY, not
  42. even that of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  It's up to
  43. you to decide if it fits your purpose.
  44. X
  45. XExcept where required by applicable law, or previously agreed in writing, 
  46. neither the author, nor the copyright holders will accept any responsibility for
  47. what you may or may not do with these programs on your systems. No liability for
  48. damage, real or imagined, direct or consequential, to you, your brain, your
  49. system or your data, (or for that matter anything else), caused by or thought to
  50. be caused  by or in any way related to QBATCH and/or it's related programs, will
  51. be accepted or even entertained. If you deem these programs suitable for
  52. installing and using on your system, you take full responsibility for them.
  53. X
  54. Whilst the QBATCH system is copyright material, it is freely distributable, and
  55. permission is hereby given to all and sundry to make what they will of it,
  56. provided that they adhere to the following:
  57. X
  58. X1.    The sources, scripts, documentation, and in particular ANY COPYRIGHT,
  59. X    LICENSE, AND DISCLAIMER NOTICES, shall remain intact and distributed
  60. X    together as a coherent unit. NO PART of the QBATCH suite shall be
  61. X    distributed separately without the express permission of the author or
  62. X    the copyright holders.
  63. X
  64. X2.    The QBATCH suite of programs shall NOT be distributed for profit.
  65. X    Distributors of freely available software may make reasonable charges
  66. X    for handling and media, but no part of it may be ascribed to the
  67. X    functionality or usefulness of QBATCH. Computer systems making software
  68. X    available to either the public, or private subscribers, internet
  69. X    archive sites and the like, are given permission to carry QBATCH, and
  70. X    make it available to their subscribers, provided no additional charges
  71. X    are made to their subscribers for doing so.
  72. X    Commercial software distributors, and software houses who may want to
  73. X    distribute QBATCH separately, as part of, or bundled with other
  74. X    commercial offerings should contact the author for written permission.
  75. X
  76. X3.    (This is more a request than a condition) If any bugs are found and
  77. X    fixed, or any enhancements are made, or any changes made in order to
  78. X    port QBATCH to a different environment, Please forward the details,
  79. X    either as modified sources, include files, or context diffs to me so
  80. X    that they can be incorporated in future releases.
  81. X
  82. X
  83. In short.. I wrote QBATCH, No one else has the right to put their name to it.
  84. X    No one else has the right to make money from my work (without me getting
  85. X        my cut!).
  86. X    If one or more of you gurus and 'nix wizards out there make a
  87. X    significant contribution to QBATCH, please get the changes to me so
  88. X    they can be incorporated in the general distribution, you will be
  89. X    duly acknowledged in the documentation.
  90. X
  91. Alan Saunders July 1991.
  92. END_OF_FILE
  93. if test 3179 -ne `wc -c <'NOTICE'`; then
  94.     echo shar: \"'NOTICE'\" unpacked with wrong size!
  95. fi
  96. # end of 'NOTICE'
  97. fi
  98. if test -f 'doc/chap.01' -a "${1}" != "-c" ; then 
  99.   echo shar: Will not clobber existing file \"'doc/chap.01'\"
  100. else
  101. echo shar: Extracting \"'doc/chap.01'\" \(4290 characters\)
  102. sed "s/^X//" >'doc/chap.01' <<'END_OF_FILE'
  103. X             QBATCH .. a queued batch processing system for UNIX
  104. X
  105. X
  106. X         The QBATCH system and its related programs were
  107. X         written by Alan D. Saunders and are
  108. X         Copyright (c) Vita Services Ltd. 1990 and
  109. X         Copyright (c) Vita Fibres Ltd. 1991
  110. X
  111. X1. INTRODUCTION
  112. X
  113. X    What is a queued batch processing system?
  114. X    Coming from a system where queued batch processing is part of the operating
  115. X    system to *NIX, I wondered how users, and administrators ever got on
  116. X    without one.  At it's simplest it is a means of submitting tasks to the
  117. X    system so that they are processed one at a time in the background.  Running
  118. X    tasks in the background is not foreign to *NIX users, they have at, batch,
  119. X    and of course '&'.  They have themselves however to keep track of the job's
  120. X    output (both stdout and stderr), and there is no formal control (except for
  121. X    permissions and access rights) over what is done, and in what order.
  122. X    A queued batch processing system is precisely that.  Tasks, or jobs
  123. X    submitted to it are placed in a queue, and are processed singly from that
  124. X    queue.
  125. X
  126. X    There are several major advantages to this approach.
  127. X   
  128. X    A. From a user's point of view, the order of processing is defined (by the
  129. X    order in which the jobs were submitted).  This means that co-operative jobs
  130. X    (jobs which rely on the output of prior jobs, and jobs which use common
  131. X    resources) can be relied upon to act correctly.
  132. X
  133. X    B. Again from the user's point of view, instead of having to wait until all
  134. X    'background' work has finished before being able to log off, (assuming he
  135. X    or she used '&') several jobs can be submitted and left to run. The results
  136. X    can be checked the next time he or she logs on.
  137. X
  138. X    C. From an administrator's point of view, the first benefit is less loading
  139. X    of system resources.  Several jobs running consecutively in a queue use
  140. X    less resources than if they were run concurrently.
  141. X
  142. X    QBATCH is an implementation of queued batch processing which provides
  143. X    additional functionality.
  144. X
  145. X    A. There can be multiple queues.  Depending on available system resources,
  146. X    rather than a single queue for all jobs, separate queues can be assigned
  147. X    for perhaps different user groups, or different job types.  This reduces
  148. X    the average time a job is queued waiting to be processed, and improves user
  149. X    satisfaction.
  150. X
  151. X    B. Queues can be prioritised.  The nice value of a process determines the
  152. X    scheduling priority assigned by the kernel.  Whilst users can 'renice'
  153. X    their processes if they are resource hogs, how often do they actually do
  154. X    so?  QBATCH queues can be assigned a nice value, to which all jobs
  155. X    processed in this queue are 'reniced' automatically when run.
  156. X
  157. X    C. QBATCH copes with job output gracefully.  There is no longer any need
  158. X    for users to remember to redirect stdout and stderr when running batch
  159. X    jobs, this is done automatically by QBATCH.  Both stdout and stderr are
  160. X    combined into a 'monitor' for the job, which for any given queue and user
  161. X    will always be written to the same place.
  162. X
  163. X    D. QBATCH queues can be started and stopped (by the super user) at ANY
  164. X    time, even from within a QBATCH job, or from cron.  This allows the
  165. X    administrator to better schedule system resources by reducing the batch
  166. X    load during periods of high interactive activity, whilst still allowing
  167. X    users to queue jobs for later processing.
  168. X
  169. X    E. Access to QBATCH queues is entirely under the control of the super user.
  170. X    Queues can be disabled (preventing anybody from submitting jobs) and
  171. X    enabled at any time.  Fixed context queues can limit access to a stated
  172. X    list of uids or gids.
  173. X
  174. X    F. Control of jobs in a queue is governed by job ownership.  The job is
  175. X    normally (except in some cases of fixed context queues) owned by the user
  176. X    submitting it.  The super user naturally has effective ownership of all
  177. X    jobs.  The owner of a job can remove it from the queue, or kill it if it is
  178. X    actually running.  He or she can change the order of their own jobs in the
  179. X    queue.  (This is limited to any consecutive group of that owners jobs, a
  180. X    user is not permitted to move a job to a position in a queue earlier than a
  181. X    job owned by another user.)
  182. END_OF_FILE
  183. if test 4290 -ne `wc -c <'doc/chap.01'`; then
  184.     echo shar: \"'doc/chap.01'\" unpacked with wrong size!
  185. fi
  186. # end of 'doc/chap.01'
  187. fi
  188. if test -f 'doc/chap.03' -a "${1}" != "-c" ; then 
  189.   echo shar: Will not clobber existing file \"'doc/chap.03'\"
  190. else
  191. echo shar: Extracting \"'doc/chap.03'\" \(3956 characters\)
  192. sed "s/^X//" >'doc/chap.03' <<'END_OF_FILE'
  193. X             QBATCH .. a queued batch processing system for UNIX
  194. X
  195. X
  196. X         The QBATCH system and its related programs were
  197. X         written by Alan D. Saunders and are
  198. X         Copyright (c) Vita Services Ltd. 1990 and
  199. X         Copyright (c) Vita Fibres Ltd. 1991
  200. X
  201. X3. ADMINISTRATION commands.
  202. X
  203. X    Note: this is a descriptive text. Full details of all the QBATCH commands
  204. X    are provided in the relevant man pages.  There is also a man page for QBATCH
  205. X    which contains a summary of all QBATCH commands.
  206. X    See also USER commands.
  207. X
  208. X    Administration commands are those accessible only to the super user
  209. X    (administrator).
  210. X
  211. X    qc    Queue create.  The administrator may create as many or as few queues as
  212. X    his system performance and his users will tolerate.  At it's simplest:
  213. X    qc name
  214. X    qc will create a file in QBATCH queue format in QUEUEPATH (defined
  215. X    during implementation) with the specified name and the following
  216. X    parameters:
  217. X
  218. X    Open.    The queue will not be fixed context, and any user can submit
  219. X             jobs.
  220. X
  221. X    Enabled. The enabled flag will be set allowing users to submit jobs
  222. X         immediately.
  223. X
  224. X    Stopped. There will be no process engine running.
  225. X
  226. X    Spooling. The default SPOOLPATH (defined during implementation) will 
  227. X         be used in which to create job files.
  228. X
  229. X    Monitor. The default monitor of SPOOLPATH/name.mon will be used.
  230. X
  231. X    Priority.The default priority or nice value of 0 (zero) will be used.
  232. X
  233. X    All of these values (except QUEUEPATH which must be fixed) may be
  234. X    varied by options to the qc program.
  235. X    If a queue already exists with the same name, then qc will apply any
  236. X    options as changes to the queue.
  237. X
  238. X    qp  Queue process. This program starts a queue process engine for the named
  239. X        queue.  An active process engine for a given queue holds an exclusive
  240. X    lock on a file in QUEUEPATH, so preventing multiple iterations of qp on
  241. X    the same queue.
  242. X
  243. X    qs  Queue stop.  This program sets the stop flag for the named queue, and
  244. X        sends a signal to the appropriate process engine.  On receipt of the
  245. X    signal, qp examines the kill flag, and if set, kills the running job.
  246. X    In any case, when the job terminates, or is killed, qp itself will
  247. X    terminate.  Any jobs left in the queue will remain (unless removed
  248. X    with jk) until the next time qp is run on this queue.  The kill flag
  249. X    may be set by qs with either of the following options:
  250. X
  251. X    -k    Set the kill flag.. cause qp to terminate immediately.
  252. X
  253. X    -r    Set the repeat and kill flags.. cause qp to terminate
  254. X        immediately but leaving the current job in the queue for
  255. X        reprocessing.
  256. X
  257. X    If neither option is used, and the kill flag is not set, the process
  258. X    engine will wait for the current job to complete before terminating.
  259. X
  260. X    Normally qs will terminate immediately it has sent a signal to the
  261. X    process engine.  qs may be forced to wait until the current job has
  262. X    finished and the process engine has terminated by using the -w option.
  263. X
  264. X    qd    Queue disable. Unset the enabled flag for a queue.  This causes js to
  265. X    reject job submissions to this queue.
  266. X
  267. X    qe  Queue enable. Set the enabled flag for a queue.  Allow users to submit
  268. X    jobs to the queue. (this is the default state).
  269. X
  270. X    qh  Queue halt. Sets the halt flag for a named queue and sends a signal to
  271. X    the appropriate process engine.  On receipt of the signal, qp checks
  272. X    the queue flags, and finding that the halt flag has been set, sends a
  273. X    SIGHALT to the job. This has the effect of halting it in it's tracks.
  274. X    The kernel will swap the job out, and will not reschedule it until the
  275. X    job receives a SIGCONT.  This can be used to hold up a particularly
  276. X    heavy job until a more appropriate time without actually killing it.
  277. X
  278. X    qg    Queue go. Unsets the halt flag for a named queue (if it is set), and
  279. X    sends a signal to the process engine. qp, on receipt of the signal,
  280. X    will send a SIGCONT to the job to resume it's processing after a
  281. X    halt.
  282. X
  283. X    qw  (cf qs -w) queue wait.  Wait for a process engine to terminate for a
  284. X    given queue.
  285. END_OF_FILE
  286. if test 3956 -ne `wc -c <'doc/chap.03'`; then
  287.     echo shar: \"'doc/chap.03'\" unpacked with wrong size!
  288. fi
  289. # end of 'doc/chap.03'
  290. fi
  291. if test -f 'doc/glossary' -a "${1}" != "-c" ; then 
  292.   echo shar: Will not clobber existing file \"'doc/glossary'\"
  293. else
  294. echo shar: Extracting \"'doc/glossary'\" \(3787 characters\)
  295. sed "s/^X//" >'doc/glossary' <<'END_OF_FILE'
  296. X
  297. X             QBATCH  a queued batch processing system for UNIX
  298. X
  299. X
  300. X         The QBATCH system and its related programs were
  301. X         written by Alan D. Saunders and are
  302. X         Copyright (c) Vita Services Ltd. 1990 and
  303. X         Copyright (c) Vita Fibres Ltd. 1991
  304. X
  305. GLOSSARY
  306. X
  307. BINDIR            The directory path specified in the Makefile, where
  308. X            the compiled program binaries will be installed.
  309. X
  310. entryno            The identifier created by js (qv) which relates
  311. X            to the position of a job in a queue.
  312. X
  313. fixed context        A queue whose fixed context flag is set and for which
  314. X            a .<queuename>rc file exists in QUEUEPATH to direct
  315. X            the submission and processing of jobs.
  316. X
  317. jcl            Commands in the syntax of the processing shell.
  318. X            (lit. 'job control language')
  319. X
  320. jclfile            file containing jcl.
  321. X
  322. jj            Job jump, program to reorder jobs in a queue.
  323. X
  324. jk            Job kill, program to remove jobs from a queue.
  325. X
  326. jm            Job monitor, program to add or change the monitor
  327. X            specification for a job in a queue.
  328. X
  329. jn            Job name, program to add or change the namestring 
  330. X            of a job in the queue.
  331. X
  332. jobcount        The number of jobs in a given queue.
  333. X
  334. jobdone            A script used to notify the submittor when a job
  335. X            has finished processing.
  336. X
  337. jobname            A meaningful name assigned to and stored with an
  338. X            entry for a job in a queue.
  339. X
  340. jobno            see entryno.
  341. X
  342. jr            Job repeat, program to cause the currently running 
  343. X            job in a queue to be rerun when it terminates.
  344. X
  345. js            Job submit, Program to submit jobs to a queue for
  346. X            queued processing.
  347. X
  348. MANDIR            The directory path specified in the Makefile, where
  349. X            the manual pages will be installed.
  350. X
  351. monitor            The output (stdout and stderr) of jobs processed in
  352. X            QBATCH queues.
  353. X
  354. monitorspec        The pathspec to which a monitor will be written.
  355. X
  356. namestring        see jobname.
  357. X
  358. prioritise        To alter the scheduling priority of jobs (nice value)
  359. X            by altering the priority field in the queue header.
  360. X
  361. qa            Queue access, script to list queues to which a user
  362. X            has submit access.
  363. X
  364. qBq            Magic word present in all QBATCH queues to identify
  365. X            them as such.
  366. X
  367. qc            Queue create, program to create QBATCH queues.
  368. X
  369. QCONTEXT        Fixed context queue directive indicating the uid
  370. X            (and gid) under which the job will run.
  371. X
  372. qd            Queue disable, Program to prevent further submissions
  373. X            to a queue.
  374. X
  375. qe            Queue enable, program to enable submissions to  queue.
  376. X
  377. QENTRY            Environment variable initialised by qp, contains the
  378. X            entryno of this job.
  379. X
  380. qf            Queue find, program to display information about a queue.
  381. X
  382. qg            Queue go, program to resume processing after a queue halt.
  383. X
  384. QGETENV            Fixed context queue directive indicating an environment
  385. X            variable to be copied to the environment of the job.
  386. X
  387. QGROUPS            Fixed context queue directive indicating a list of groups
  388. X            permitted to submit jobs to this queue.
  389. X
  390. qh            Queue halt, program to suspend processing of the current
  391. X            job in a queue.
  392. X
  393. ql            Queue list, program to list the contents of a queue.
  394. X
  395. qp            Queue process, program to initiate processing of jobs
  396. X            in a queue.
  397. X
  398. qs            Queue stop. program to stop further jobs being processed
  399. X            in a queue.    
  400. X
  401. qt            Queue test, program to test and return queue status.
  402. X
  403. queuename        
  404. qname            Name of a file in QUEUEPATH which is a QBATCH queue.
  405. X
  406. QUEUEPATH        The directory path specified in the Makefile where
  407. X            QBATCH queues will be created and used.
  408. X
  409. QUSERS            Fixed context queue directive indicating a list of
  410. X            users permitted to submit jobs to this queue.
  411. X
  412. qw            Queue wait, program which waits until a queue is idle.
  413. X
  414. qxenv            File in QUEUEPATH containing a list of environment 
  415. X            variables which are NOT to be transferred to the
  416. X            environment of a job.
  417. X
  418. SPOOLPATH        The directory path specified in the Makefile, where
  419. X            js will create jcl files, and where qp will read them.
  420. X
  421. submittor        The user submitting a job to a queue.
  422. END_OF_FILE
  423. if test 3787 -ne `wc -c <'doc/glossary'`; then
  424.     echo shar: \"'doc/glossary'\" unpacked with wrong size!
  425. fi
  426. # end of 'doc/glossary'
  427. fi
  428. if test -f 'man/js.l' -a "${1}" != "-c" ; then 
  429.   echo shar: Will not clobber existing file \"'man/js.l'\"
  430. else
  431. echo shar: Extracting \"'man/js.l'\" \(4394 characters\)
  432. sed "s/^X//" >'man/js.l' <<'END_OF_FILE'
  433. X.TH JS 1L "14 May 1991" JS "QUEUED BATCH PROCESSING SYSTEM"
  434. X.SH COPYRIGHT
  435. The
  436. X.B QBATCH
  437. system and its related programs are Copyright:
  438. X.br
  439. X(c) Vita Services Ltd. 1990
  440. X.br
  441. X(c) Vita Fibres Ltd. 1991
  442. X.SH NAME 
  443. X.B js
  444. X\- job submit. submit a job to an named queue.
  445. X.SH SYNOPSIS
  446. X.B js
  447. X[
  448. X.B \-dl
  449. X]
  450. X[
  451. X.BI \-m " monitor"
  452. X]
  453. X[
  454. X.BI \-n " jobname"
  455. X]
  456. X[
  457. X.BI \-r " reply"
  458. X]
  459. X.br
  460. X[
  461. X.BI \-s " shell"
  462. X]
  463. X.B queuename
  464. X[
  465. X.B jclfile
  466. X]
  467. X|[
  468. X.BI \-v
  469. X]
  470. X.SH DESCRIPTION
  471. A temporary file is created in the spooling directory specified in the
  472. queue header. If the queue is not a fixed context queue, the current
  473. environment of the user is copied into it, certain environment
  474. variables may be excluded from this copy if they are listed in a .qxenv
  475. file in the directory containing the queuefiles. If the queue is fixed context, jcl is
  476. generated to provide an environment and context as specified in the rc
  477. file for the queue.  If the jcl file is provided, either a line of jcl
  478. containing the pathspec of it is placed in the temporary file (-l
  479. option), or it's contents are copied into the temporary file. If the
  480. jcl file is not provided, stdin is copied into the temporary file up to
  481. an eof. (this allows for piped jcl). An entry is added to the end of
  482. the queue file, and if the queue is being processed, a signal is sent
  483. to the pid of the process engine for the queue.
  484. X.SH OPTIONS
  485. X.TP 12
  486. X.B  \-d
  487. Debug. Creates the job file with the -x switch set so that
  488. the monitor echoes all commands as they are executed (silently
  489. ignored if a shell is specified with the -s option).
  490. X.TP
  491. X.B  \-l
  492. Link. Do not copy the jcl file into the spool directory.
  493. Instead, create a smaller jcl file containing a call to it.
  494. This allows large jcl files to be processed without taking
  495. too much disk space.
  496. X.br
  497. NOTE: Because js needs to create the jcl file to set up the environment for the job,
  498. X(and possible script commands and directives in the case of fixed context queues), jcl
  499. linked in this way must be totally self-contained.  The environment is NOT copied in the case
  500. of a linked job, and this option is not permitted for fixed context queues.
  501. X.TP
  502. X.BI  \-m " monitor"
  503. Specify a non-default monitor for this job. If this
  504. is not specified, the monitor (stdout and stderr) for the
  505. job will be that specified in the queue header. If the 
  506. monitor specified here is a path rather than a file, the
  507. filename xxxx.mon will be used in that path, where xxxx 
  508. is the first four characters of the queue name.
  509. X.TP
  510. X.BI \-n " jobname"
  511. Specify a descriptive name for this job, which will
  512. be displayed when ql is run.
  513. X.br
  514. NOTE: If a name is not specified for a given job, js
  515. will assume that the job is being submitted through
  516. a batch process, and will use the first 30 bytes of the LAST
  517. line of the jcl as the job name. Normally, if this
  518. is the case, the jcl will only consist of a single line
  519. X(a macro call) and this default will include the macro
  520. name. If the jcl consists of more than one line (after
  521. setting up the job environment), it is recommended that
  522. an additional (comment) line is added at the end, to
  523. generate a meaningful job name.
  524. X.TP
  525. X.BI \-r " n"
  526. Reply. Notify the user when the job is finished.
  527. n may have one of the following values:
  528. X.nf
  529. X0 No reply required. (the default).
  530. X1 Write a message on the users tty.
  531. X2 Send mail to the user.
  532. X.fi
  533. Any other value results in NO notification.
  534. X.TP
  535. X.BI \-s " shell"
  536. Specify the shell under which the batch job is run. This should
  537. be the full pathspec of the executable file which will be run
  538. to interpret this jcl script. If the executable requires arguments
  539. the group of path and arguments should be surrounded by quotes.
  540. When a shell (possibly including switches or arguments) is specified,
  541. the debug (-d) switch is silently ignored (it is specific to the Bourne shell).
  542. X.br
  543. If the queue is a fixed context queue, and the first line of the control file
  544. starts with '#!/' (i.e. is a directive to use a particular shell) then the -s
  545. option is silently ignored.
  546. X.br
  547. eg. -s "/bin/sh -x"
  548. X.TP
  549. X.BI \-v
  550. Display QBATCH version and copyright information.
  551. X.SH FILES
  552. X.ft B
  553. QUEUEPATH/<queue files>
  554. QUEUEPATH/.qxenv
  555. X.SH "SEE ALSO"
  556. X.BR qbatch (1L)
  557. X.BR jj (1L)
  558. X.BR jk (1L)
  559. X.BR jm (1L)
  560. X.BR jn (1L)
  561. X.BR jr (1L)
  562. X.BR qa (1L)
  563. X.BR qc (8L)
  564. X.BR qd (1L)
  565. X.BR qe (1L)
  566. X.BR qf (1L)
  567. X.BR qg (1L)
  568. X.BR qh (1L)
  569. X.BR ql (1L)
  570. X.BR qp (1L)
  571. X.BR qs (1L)
  572. X.BR qt (1L)
  573. X.BR qw (1L)
  574. X.BR rc.QBATCH (8L)
  575. X.BR jobdone (8L)
  576. X.BR queue (5L)
  577. X.BR qxenv (5L)
  578. END_OF_FILE
  579. if test 4394 -ne `wc -c <'man/js.l'`; then
  580.     echo shar: \"'man/js.l'\" unpacked with wrong size!
  581. fi
  582. # end of 'man/js.l'
  583. fi
  584. if test -f 'man/qf.l' -a "${1}" != "-c" ; then 
  585.   echo shar: Will not clobber existing file \"'man/qf.l'\"
  586. else
  587. echo shar: Extracting \"'man/qf.l'\" \(3581 characters\)
  588. sed "s/^X//" >'man/qf.l' <<'END_OF_FILE'
  589. X.TH QF 1L "14 May 1991" QF "QUEUED BATCH PROCESSING SYSTEM"
  590. X.SH COPYRIGHT
  591. The
  592. X.B QBATCH
  593. system and its related programs are Copyright:
  594. X.br
  595. X(c) Vita Services Ltd. 1990
  596. X.br
  597. X(c) Vita Fibres Ltd. 1991
  598. X.SH NAME 
  599. X.B qf
  600. X\- Queue find. Find out information about the named queue.
  601. X.SH SYNOPSIS
  602. X.B qf 
  603. X\-[
  604. X.B a
  605. X]|[
  606. X.B l
  607. X]|[
  608. X.B n
  609. X]|[
  610. X.B p
  611. X]|[
  612. X.B q
  613. X]|[
  614. X.B r
  615. X]|[
  616. X.B s
  617. X]
  618. X.B qname
  619. X.br
  620. X.B qf 
  621. X[
  622. X.BI \-e " entryno"
  623. X] [ -[
  624. X.B j
  625. X]|[
  626. X.B m
  627. X]]
  628. X.B qname
  629. X.br
  630. X.B qf 
  631. X[
  632. X.BI \-v
  633. X]
  634. X.SH DESCRIPTION
  635. This function is provided for the convenience of the
  636. user, in that frequently this information is needed
  637. in order to examine job monitors, or jcl files. Rather
  638. than having to determine this information in some other
  639. way (ql for example), and then enter it manually, The
  640. shell facilities of UNIX can be utilised viz:
  641. X.br
  642. tail `qf -m sopt`
  643. X.br
  644. or vi `qf -e7 work`
  645. X.SH OPTIONS
  646. X.TP 12
  647. X.B  \-a
  648. Activity. Actually reports back the number of entries 
  649. in the queue on stdout. As with the p option, 
  650. this is used in rc.QBATCH to determine whether there
  651. was a job in the queue at closedown. If there was,
  652. rc.QBATCH will sleep for 20 seconds after restarting
  653. the process engine, to allow jobs to process to a 'settled'
  654. state before processing any other queues.
  655. X.TP
  656. X.BI \-e " n"
  657. XEntry no <n>. modifies the action of -m and -j to report
  658. either the monitor or jcl file of queue entry no n.
  659. X.TP
  660. X.B  \-j
  661. JCL. Reports the full pathspec of the JCL file of the
  662. first entry in the queue. (Normally the running job.)
  663. X.TP
  664. X.B \-l
  665. Line. Produces a brief status report on the queue header.  The report is headed with the
  666. field descriptions and consists a single line of data.
  667. X.RS -6
  668. viz:
  669. X
  670. X.nf
  671. Queue   No of     Priority    Fixed   Enabled  Halted  Stopped
  672. Name    Entries    (nice)     Context
  673. X
  674. sopt      0          0          no       yes     no      no 
  675. X
  676. X.RE
  677. X.fi
  678. The similar (-l) option to qt is identical but without the headings.
  679. X.TP 12
  680. X.B  \-m
  681. Monitor. Reports the full pathspec of the monitor in
  682. use or to be used by the first job in the queue.
  683. X.TP
  684. X.B \-n
  685. Nice value. Reports the priority or nice value stored in the queue header.
  686. X.TP
  687. X.B  \-p
  688. PID. Reports the pid stored in the queue header. This
  689. is normally either the pid of the queue process
  690. engine activity, or zero if the queue is stopped.
  691. The exception is when the queue has stopped processing
  692. abnormally (i.e without being stopped with qs), usually
  693. by a system shutdown. Then there will be a pid stored,
  694. but there will be no process activity. Like the -a option, this is used
  695. by rc.QBATCH to determine if a queue was being processed
  696. when the system was closed down. If it was, rc.QBATCH will start a new
  697. process engine.
  698. X.TP
  699. X.B  \-q
  700. Queue default monitor. Reports the full pathspec of
  701. the default monitor.
  702. X.TP
  703. X.B \-r
  704. Running job. Reports the pid of the currently running job.
  705. X.TP
  706. X.B \-s
  707. Summary timings. Reports a brief summary of the activity of the queue, both as total time
  708. taken , and as average per job. The times reported are Queued (time on queue before being
  709. processed) real (wall clock), user, and system cpu time. They are reported as DD:HH:MM:SS.ss.
  710. If the queue is being processed when 
  711. X.B qf
  712. is run, it will also report queue utilisation as a percentage of availability.
  713. X.TP
  714. X.B \-v
  715. Display QBATCH version and copyright information.
  716. X.SH FILES
  717. X.ft B
  718. QUEUEPATH/*
  719. X.SH "SEE ALSO"
  720. X.BR qbatch (1L)
  721. X.BR jj (1L)
  722. X.BR jk (1L)
  723. X.BR jm (1L)
  724. X.BR jn (1L)
  725. X.BR jr (1L)
  726. X.BR js (1L)
  727. X.BR qa (1L)
  728. X.BR qc (8L)
  729. X.BR qd (1L)
  730. X.BR qe (1L)
  731. X.BR qg (1L)
  732. X.BR qh (1L)
  733. X.BR ql (1L)
  734. X.BR qp (1L)
  735. X.BR qs (1L)
  736. X.BR qt (1L)
  737. X.BR qw (1L)
  738. X.BR rc.QBATCH (8L)
  739. X.BR jobdone (8L)
  740. X.BR queue (5L)
  741. X.BR qxenv (5L)
  742. END_OF_FILE
  743. if test 3581 -ne `wc -c <'man/qf.l'`; then
  744.     echo shar: \"'man/qf.l'\" unpacked with wrong size!
  745. fi
  746. # end of 'man/qf.l'
  747. fi
  748. if test -f 'man/qt.l' -a "${1}" != "-c" ; then 
  749.   echo shar: Will not clobber existing file \"'man/qt.l'\"
  750. else
  751. echo shar: Extracting \"'man/qt.l'\" \(2882 characters\)
  752. sed "s/^X//" >'man/qt.l' <<'END_OF_FILE'
  753. X.TH QF 1L "14 May 1991" QF "QUEUED BATCH PROCESSING SYSTEM"
  754. X.SH COPYRIGHT
  755. The
  756. X.B QBATCH
  757. system and its related programs are Copyright:
  758. X.br
  759. X(c) Vita Services Ltd. 1990
  760. X.br
  761. X(c) Vita Fibres Ltd. 1991
  762. X.SH NAME 
  763. X.B qt
  764. X\- Queue test. Test various aspects of the queue status.
  765. X.SH SYNOPSIS
  766. X.B qt 
  767. X\-[
  768. X.B e
  769. X]|[
  770. X.B f
  771. X]|[
  772. X.B h
  773. X]|[
  774. X.B k
  775. X]|[
  776. X.B l
  777. X]|[
  778. X.B r
  779. X]|[
  780. X.B s
  781. X]|[
  782. X.B t
  783. X]|[
  784. X.B u
  785. X]
  786. X.B qname
  787. X.br
  788. X.B qt 
  789. X[
  790. X.BI \-v
  791. X]
  792. X.SH DESCRIPTION
  793. This function is provided for use in scripts. 
  794. X.B qt
  795. will either fail, or not fail depending on the result of the test carried out.
  796. Most tests (except -t and -u) simply check whether one of the header flags is set.
  797. X.SH OPTIONS
  798. X.TP 12
  799. X.B  \-e
  800. XEnabled flag. 
  801. X.B qt
  802. will fail if the enabled flag is not set.
  803. X(queue is not accepting entries) it will not fail if the queue is accepting entries.
  804. X.TP
  805. X.B  \-f
  806. XFixed context flag. 
  807. X.B qt
  808. will fail if the fixed context flag is not set.
  809. X(queue is not fixed context) It will not fail if the queue is fixed context.
  810. X.TP
  811. X.B  \-h
  812. Halt flag. 
  813. X.B qt
  814. will fail if the halt flag is not set.
  815. X(Current job is not halted) It will not fail if the job is halted.
  816. X.TP
  817. X.B  \-k
  818. Kill flag. 
  819. X.B qt
  820. will fail if the kill flag is not set.
  821. X(last job was not killed) It will not fail if the last job was killed.
  822. X.TP
  823. X.B \-l
  824. Line. Produces a brief single line status report on the queue header if the user may submit jobs
  825. to this queue. (see -u option) This is mainly included for use by the qa script (qv).
  826. X.RS -6
  827. viz:
  828. X.nf
  829. X
  830. sopt      0          0          no       yes     no      no 
  831. X
  832. X.RE
  833. X.fi
  834. The similar (-l) option to qf is identical but with headings for the columns.
  835. X.TP
  836. X.B  \-r
  837. Repeat flag. 
  838. X.B qt
  839. will fail if the repeat flag is not set.
  840. X(current job is not to be repeated) It will not fail if the job is to be (is being) repeated)
  841. X.TP
  842. X.B  \-s
  843. stop flag. 
  844. X.B qt
  845. will fail if the stop flag is not set.
  846. X(queue will not stop after current job) It will not fail if the queue will stop after the
  847. current job or is already stopped.
  848. X.TP
  849. X.B  \-t
  850. Test queue.
  851. X.B qt
  852. will fail if the queue is not a valid
  853. X.B QBATCH
  854. queue. 
  855. X.TP
  856. X.B  \-u
  857. Use (can I?)
  858. X.B qt
  859. Tests the accessibility of the queue for the currently logged in user context.
  860. If the queue is not fixed context, or if this user can submit jobs to this fixed context queue,
  861. X.B qt
  862. will not fail.
  863. X.B qt
  864. will fail if this queue is a fixed context queue, and this user's uid or gid do not appear
  865. in a #QUSERS or #QGROUPS directive for this queue (if these directives exist for this queue)
  866. X.B qt
  867. X.TP
  868. X.B \-v
  869. Display QBATCH version and copyright information.
  870. X.SH FILES
  871. X.ft B
  872. QUEUEPATH/*
  873. X.SH "SEE ALSO"
  874. X.BR qbatch (1L)
  875. X.BR jj (1L)
  876. X.BR jk (1L)
  877. X.BR jm (1L)
  878. X.BR jn (1L)
  879. X.BR jr (1L)
  880. X.BR js (1L)
  881. X.BR qa (1L)
  882. X.BR qc (8L)
  883. X.BR qd (1L)
  884. X.BR qe (1L)
  885. X.BR qf (1L)
  886. X.BR qg (1L)
  887. X.BR qh (1L)
  888. X.BR ql (1L)
  889. X.BR qp (1L)
  890. X.BR qs (1L)
  891. X.BR qt (1L)
  892. X.BR qw (1L)
  893. X.BR rc.QBATCH (8L)
  894. X.BR jobdone (8L)
  895. X.BR queue (5L)
  896. X.BR qxenv (5L)
  897. END_OF_FILE
  898. if test 2882 -ne `wc -c <'man/qt.l'`; then
  899.     echo shar: \"'man/qt.l'\" unpacked with wrong size!
  900. fi
  901. # end of 'man/qt.l'
  902. fi
  903. if test -f 'man/queue.l' -a "${1}" != "-c" ; then 
  904.   echo shar: Will not clobber existing file \"'man/queue.l'\"
  905. else
  906. echo shar: Extracting \"'man/queue.l'\" \(3956 characters\)
  907. sed "s/^X//" >'man/queue.l' <<'END_OF_FILE'
  908. X.TH QUEUE 5L "11 May 1991" QUEUE "QUEUED BATCH PROCESSING SYSTEM"
  909. X.SH COPYRIGHT
  910. The
  911. X.B QBATCH
  912. system and its related programs are Copyright:
  913. X.br
  914. X(c) Vita Services Ltd. 1990
  915. X.br
  916. X(c) Vita Fibres Ltd. 1991
  917. X.SH NAME 
  918. X.B queue
  919. X\- Description of a qbatch queue file.
  920. X.SH SYNOPSIS
  921. X.ft B
  922. X#include "qbatch.h"
  923. X.SH DESCRIPTION
  924. A queue is a file used by the
  925. X.B QBATCH
  926. system to store information about the queue and it's process engine, and about
  927. jobs queued therein. The queue has two parts. The header contains the variable data
  928. and defaults for the queue:
  929. X.sp
  930. X.nf
  931. X    
  932. struct queue_header {
  933. X    char          q_magic[4];
  934. X    pid_t            qh_pid;
  935. X    int            qh_noentries;
  936. X    int            qh_hiwater;
  937. X    int            qh_priority;
  938. X    unsigned int    qh_flags;
  939. X    time_t         qh_proc;
  940. X    time_t         qh_start;
  941. X    time_t         qh_queued;
  942. X    long           qh_real;
  943. X    long           qh_user;
  944. X    long           qh_system;
  945. X    long           qh_jobcount;
  946. X    char           qh_spool[64];
  947. X    char           qh_defmon[64];
  948. X};
  949. X.fi
  950. X.sp
  951. XField contents are :
  952. X.TP 15
  953. X.B q_magic
  954. Identification of a queue.
  955. X.TP
  956. X.B qh_pid
  957. Process id of the qp activity handling this queue.
  958. X.TP
  959. X.B qh_noentries
  960. current number of entries
  961. X.TP
  962. X.B qh_hiwater
  963. highest job entry number in queue
  964. X.TP
  965. X.B qh_priority
  966. Priority or 'nice' value of process
  967. X.TP
  968. X.B qh_flags
  969. qh_flags is a bit encoded unsigned integer.
  970. If qh_flags masked with the defined valued below is greater than zero,
  971. the flag is set.
  972. X.TP
  973. X.B qh_proc
  974. time queue started processing
  975. X.TP
  976. X.B qh_start
  977. time current job started
  978. X.TP
  979. X.B qh_queued
  980. Total time spent queued (before processing)
  981. X.TP
  982. X.B qh_real
  983. total process time for jobs in this queue
  984. X.TP
  985. X.B qh_user
  986. total user CPU time for jobs in this queue
  987. X.TP
  988. X.B qh_system
  989. total system CPU time for jobs in this queue
  990. X.TP
  991. X.B qh_jobcount
  992. total no of jobs processed
  993. X.TP
  994. X.B qh_spool
  995. spool file directory for this queue
  996. X.br
  997. X(default is /usr/spool)
  998. X.TP
  999. X.B qh_defmon
  1000. default monitor for queue 
  1001. X.br
  1002. X(default is <qh_spool>/<qname>.mon)
  1003. X.sp 2
  1004. X.TP 0
  1005. X.nf
  1006. Bitmap of qh_flags:
  1007. X.sp
  1008. X#define    qh_repeat    1              /* repeat current job flag  */
  1009. X#define    qh_kill      2              /* kill current job flag    */
  1010. X#define    qh_stop      4              /* stop processing flag     */
  1011. X#define    qh_enabled   8              /* accept entries flag      */
  1012. X#define    qh_halt     16              /* suspend processing flag  */
  1013. X#define    qh_fixed    32              /* fixed context processing */
  1014. X#define    qh_flagmax  32              /* should be highest above  */
  1015. X#define    qh_action qh_kill + qh_halt /* immediate action flags   */
  1016. X.sp 2
  1017. X.fi
  1018. The header is followed by a variable number of queue entries (as defined in
  1019. qh_noentries), one for each job in the queue:
  1020. X.sp
  1021. X.nf
  1022. struct queue_entry {
  1023. X        int        qe_jobno;
  1024. X        int        qe_status;
  1025. X        int        qe_repcount;
  1026. X        int        qe_notify;
  1027. X        uid_t        qe_uid;
  1028. X        gid_t        qe_gid;
  1029. X        time_t     qe_submitted;
  1030. X        char       qe_uname[16];
  1031. X        char       qe_tty[8];
  1032. X        char       qe_jobname[32];
  1033. X        char       qe_jcl[64];
  1034. X        char       qe_monitor[64];
  1035. X};
  1036. X.fi
  1037. X.TP 15
  1038. X.B qe_jobno
  1039. identifier for this job
  1040. X.TP
  1041. X.B qe_status
  1042. flag set (to it's pid)  if this job is 
  1043. running
  1044. X.TP
  1045. X.B qe_repcount
  1046. internal flag for environment
  1047. X.TP
  1048. X.B qe_notify
  1049. notification flag:
  1050. X.br
  1051. X.nf
  1052. X0 = none
  1053. X1 = display message
  1054. X2 = mail
  1055. X.fi
  1056. X.TP
  1057. X.B qe_uid
  1058. uid of activity submitting this job
  1059. X.TP
  1060. X.B qe_gid
  1061. gid of activity submitting this job
  1062. X.TP
  1063. X.B qe_submitted
  1064. time this job was submitted
  1065. X.TP
  1066. X.B qe_uname
  1067. user name of submittor
  1068. X.TP
  1069. X.B qe_tty
  1070. user's terminal if interactive
  1071. X.TP
  1072. X.B qe_jobname
  1073. optional user job name
  1074. X.TP
  1075. X.B qe_jcl
  1076. filename of job file submitted
  1077. X.TP
  1078. X.B qe_monitor
  1079. monitor file for this job if not
  1080. default
  1081. X.SH OPTIONS
  1082. X.SH FILES
  1083. X.ft B
  1084. QUEUEPATH/*
  1085. X.SH "SEE ALSO"
  1086. X.BR qbatch (1L)
  1087. X.BR jj (1L)
  1088. X.BR jk (1L)
  1089. X.BR jm (1L)
  1090. X.BR jn (1L)
  1091. X.BR jr (1L)
  1092. X.BR js (1L)
  1093. X.BR qa (1L)
  1094. X.BR qc (8L)
  1095. X.BR qd (1L)
  1096. X.BR qe (1L)
  1097. X.BR qf (1L)
  1098. X.BR qg (1L)
  1099. X.BR qh (1L)
  1100. X.BR ql (1L)
  1101. X.BR qp (1L)
  1102. X.BR qt (1L)
  1103. X.BR qs (1L)
  1104. X.BR qw (1L)
  1105. X.BR rc.QBATCH (8L)
  1106. X.BR jobdone (8L)
  1107. X.BR qxenv (5L)
  1108. END_OF_FILE
  1109. if test 3956 -ne `wc -c <'man/queue.l'`; then
  1110.     echo shar: \"'man/queue.l'\" unpacked with wrong size!
  1111. fi
  1112. # end of 'man/queue.l'
  1113. fi
  1114. if test -f 'src/jm.c' -a "${1}" != "-c" ; then 
  1115.   echo shar: Will not clobber existing file \"'src/jm.c'\"
  1116. else
  1117. echo shar: Extracting \"'src/jm.c'\" \(3130 characters\)
  1118. sed "s/^X//" >'src/jm.c' <<'END_OF_FILE'
  1119. X/************************************************************************/  
  1120. X/*                                                                      */
  1121. X/* jm .. job monitor. Add or alter monitor for a given job              */
  1122. X/*                                                                      */
  1123. X/*      usage: jn [-e<entryno>]  qname namestring                    */
  1124. X/*                                                                      */
  1125. X/*   Copyright (c) Vita Services 1990                                   */
  1126. X/*             (c) Vita Fibres   1990 1991                              */
  1127. X/*                                                                      */
  1128. X/************************************************************************/
  1129. X
  1130. X#include "qbatch.h"
  1131. int fpq = 0;
  1132. int j, entryno = 0;
  1133. uid_t uid;
  1134. int changed = 0;
  1135. char *queuename;
  1136. char queue[128];
  1137. char buff [128];                            
  1138. X#include "config.h"
  1139. X
  1140. main (argc, argv, envp)
  1141. int argc;
  1142. char *argv[], *envp[];
  1143. X{
  1144. X    int c;
  1145. X    extern char *optarg;
  1146. X    extern int optind;
  1147. X    while ((c = getopt (argc, argv, "e:v")) != -1)
  1148. X    switch (c)
  1149. X    {
  1150. X        case 'e':   entryno = atoi (optarg);
  1151. X                    break;
  1152. X        case 'v':   q_version();
  1153. X    case '?':   qb_term (-1);
  1154. X    }
  1155. X    if (optind >= argc)
  1156. X    {
  1157. X        fprintf(stderr,"Usage: jm -e<entryno> queuename monitorspec\n");
  1158. X        exit (-1);
  1159. X    }
  1160. X    queuename = argv[optind];
  1161. X    strcpy (queue, QUEUEPATH);
  1162. X    strcat (queue, queuename);
  1163. X    qb_setterm();
  1164. X    fpq = open (queue, O_RDWR);
  1165. X    if (fpq == -1)
  1166. X    {
  1167. X        fprintf (stderr, "Invalid queue name: %s\n", queuename);
  1168. X        qb_term (-1); 
  1169. X    }
  1170. X    optind ++;
  1171. X    if (argc <= optind)
  1172. X    {
  1173. X        fprintf (stderr, "Missing monitor path\n");
  1174. X        qb_term (-1);
  1175. X    }
  1176. X    argv[optind][63] = 0;
  1177. X    q_lock(fpq);
  1178. X    read  (fpq, &head, sizeof(head));
  1179. X    if (bad_queue()) qb_exit(-1);
  1180. X    j = lseek (fpq, 0, SEEK_CUR);
  1181. X    read  (fpq, &entry, sizeof(entry));
  1182. X    uid = geteuid();
  1183. X    if (uid != 0 && uid != entry.qe_uid)
  1184. X    {
  1185. X        fprintf (stderr, "Must own the job or be super user to change monitor\n");
  1186. X        qb_term (-1);
  1187. X    }
  1188. X    if (entryno != 0 && entryno != entry.qe_jobno)
  1189. X    {
  1190. X        while (entryno != entry.qe_jobno)
  1191. X        {
  1192. X            j = lseek (fpq, 0, SEEK_CUR);
  1193. X            read (fpq, &entry, sizeof(entry));
  1194. X        }
  1195. X    }
  1196. X    if (strcmp (entry.qe_monitor, argv[optind]) != 0) changed ++; /* changed monitor */
  1197. X    if (entry.qe_status != 0)                                     /* job active */
  1198. X    {
  1199. X        if (changed)
  1200. X        {
  1201. X            if ((head.qh_flags &qh_repeat) == 0) head.qh_flags += qh_repeat;
  1202. X            if ((head.qh_flags &qh_kill) == 0) head.qh_flags += qh_kill;
  1203. X        }
  1204. X    }
  1205. X    strcpy (entry.qe_monitor, argv[optind]);
  1206. X    lseek (fpq, 0, SEEK_SET);
  1207. X    write (fpq, &head, sizeof(head));
  1208. X    lseek (fpq, j, SEEK_SET);
  1209. X    write (fpq, &entry, sizeof(entry));
  1210. X    if (changed) printf ("Monitor redirected to %s\n", entry.qe_monitor);
  1211. X    else         printf ("Monitor unchanged\n");
  1212. X    fflush (stdout);
  1213. X    q_unlock(fpq);
  1214. X    close(fpq); fpq = 0;
  1215. X    tell_qp();
  1216. X    qb_term(0);
  1217. X}
  1218. END_OF_FILE
  1219. if test 3130 -ne `wc -c <'src/jm.c'`; then
  1220.     echo shar: \"'src/jm.c'\" unpacked with wrong size!
  1221. fi
  1222. # end of 'src/jm.c'
  1223. fi
  1224. if test -f 'src/jn.c' -a "${1}" != "-c" ; then 
  1225.   echo shar: Will not clobber existing file \"'src/jn.c'\"
  1226. else
  1227. echo shar: Extracting \"'src/jn.c'\" \(2563 characters\)
  1228. sed "s/^X//" >'src/jn.c' <<'END_OF_FILE'
  1229. X/************************************************************************/  
  1230. X/*                                                                      */
  1231. X/* jn .. job name. Add or alter name for a given job                    */
  1232. X/*                                                                      */
  1233. X/*      usage: jn [-e<entryno>]  qname namestring                    */
  1234. X/*                                                                      */
  1235. X/*   Copyright (c) Vita Services 1990                                   */
  1236. X/*             (c) Vita Fibres   1990 1991                              */
  1237. X/*                                                                      */
  1238. X/************************************************************************/
  1239. X
  1240. X#include "qbatch.h"
  1241. int fpq = 0;
  1242. int j, entryno = 0;
  1243. uid_t uid;
  1244. char *queuename;
  1245. char queue[128];
  1246. char buff [128];                            
  1247. X#include "config.h"
  1248. X                            
  1249. X
  1250. main (argc, argv)
  1251. int argc;
  1252. char *argv[];
  1253. X{
  1254. X    int c;
  1255. X    extern char *optarg;
  1256. X    extern int optind;
  1257. X    while ((c = getopt (argc, argv, "e:v")) != -1)
  1258. X    switch (c)
  1259. X    {
  1260. X        case 'e':   entryno = atoi (optarg);
  1261. X                    break;
  1262. X        case 'v':   q_version();
  1263. X    case '?':   qb_term (-1);
  1264. X    }
  1265. X    if (optind >= argc)
  1266. X    {
  1267. X        fprintf (stderr, "Usage: jn [-e<entryno>]  qname namestring\n");
  1268. X        exit (-1);
  1269. X    }
  1270. X    queuename = argv[optind];
  1271. X    strcpy (queue, QUEUEPATH);
  1272. X    strcat (queue, queuename);
  1273. X    qb_setterm();
  1274. X    fpq = open (queue, O_RDWR);
  1275. X    if (fpq == -1)
  1276. X    {
  1277. X        fprintf (stderr, "Invalid queue name: %s\n", queuename);
  1278. X        qb_term (-1); 
  1279. X    }
  1280. X    optind ++;
  1281. X    if (argc <= optind)
  1282. X    {
  1283. X        fprintf (stderr, "Missing job name\n");
  1284. X        qb_term (-1);
  1285. X    }
  1286. X    argv[optind][30] = 0;
  1287. X    q_lock(fpq);
  1288. X    read  (fpq, &head, sizeof(head));
  1289. X    if (bad_queue()) qb_exit(-1);
  1290. X    j = lseek (fpq, 0, SEEK_CUR);
  1291. X    read  (fpq, &entry, sizeof(entry));
  1292. X    uid = geteuid();
  1293. X    if (uid != 0 && uid != entry.qe_uid)
  1294. X    {
  1295. X        fprintf (stderr, "Must own the job or be super user to name it\n");
  1296. X        qb_term (-1);
  1297. X    }
  1298. X    if (entryno != 0 && entryno != entry.qe_jobno)
  1299. X    {
  1300. X        while (entryno != entry.qe_jobno)
  1301. X        {
  1302. X            j = lseek (fpq, 0, SEEK_CUR);
  1303. X            read (fpq, &entry, sizeof(entry));
  1304. X        }
  1305. X    }
  1306. X    strcpy (entry.qe_jobname, argv[optind]);
  1307. X    lseek (fpq, 0, SEEK_SET);
  1308. X    write (fpq, &head, sizeof(head));
  1309. X    lseek (fpq, j, SEEK_SET);
  1310. X    write (fpq, &entry, sizeof(entry));
  1311. X    q_unlock(fpq);
  1312. X    close (fpq); fpq = 0;
  1313. X    qb_term(0);
  1314. X}
  1315. END_OF_FILE
  1316. if test 2563 -ne `wc -c <'src/jn.c'`; then
  1317.     echo shar: \"'src/jn.c'\" unpacked with wrong size!
  1318. fi
  1319. # end of 'src/jn.c'
  1320. fi
  1321. if test -f 'src/qbatch.h' -a "${1}" != "-c" ; then 
  1322.   echo shar: Will not clobber existing file \"'src/qbatch.h'\"
  1323. else
  1324. echo shar: Extracting \"'src/qbatch.h'\" \(3583 characters\)
  1325. sed "s/^X//" >'src/qbatch.h' <<'END_OF_FILE'
  1326. X/************************************************************************/  
  1327. X/*                                                                      */
  1328. X/* qbatch.h qbatch local header file                                    */
  1329. X/*                                                                      */
  1330. X/*   Copyright (c) Vita Services 1990                                   */
  1331. X/*             (c) Vita Fibres   1990 1991                              */
  1332. X/*                                                                      */
  1333. X/************************************************************************/
  1334. X#include <stdio.h>
  1335. X#include <string.h>
  1336. X#include <sys/file.h>
  1337. X#include <sys/types.h>
  1338. X#include <unistd.h>
  1339. X
  1340. X#include "patchlevel.h"
  1341. X#include "what.h"
  1342. static char QbCR1 []= "@(#) Copyright (c) Vita Services 1990";
  1343. static char QbCR2 []= "@(#)           (c) Vita Fibres   1990 1991";
  1344. X
  1345. X/* structure of flag byte */
  1346. X#define    qh_repeat    1    /* repeat current job flag */
  1347. X#define    qh_kill      2    /* kill current job flag */
  1348. X#define    qh_stop      4    /* stop processing flag */
  1349. X#define    qh_enabled   8       /* accept entries flag */
  1350. X#define    qh_halt     16       /* suspend processing flag */
  1351. X#define       qh_fixed    32       /* fixed context processing */
  1352. X#define    qh_flagmax  32       /* should be highest above */
  1353. X#define    qh_action qh_kill + qh_halt /* immediate action flags */
  1354. X
  1355. struct queue_header {
  1356. X    char   q_magic[4];
  1357. X    pid_t  qh_pid;        /* Process id of the qp activity 
  1358. X                   handling this queue. */
  1359. X    int    qh_noentries;    /* current number of entries */
  1360. X    int    qh_hiwater;          /* highest jobid in queue */
  1361. X    int    qh_priority;            /* 'nice' value of process */
  1362. X    unsigned int  qh_flags;     /* see above */
  1363. X    time_t qh_proc;        /* time queue started processing */
  1364. X    time_t qh_start;            /* time current job started */
  1365. X    time_t qh_queued;        /* Total time spent queued (before processing) */
  1366. X    long   qh_real;        /* total process time for jobs in this queue */
  1367. X    long   qh_user;        /* total user CPU time for jobs in this queue */
  1368. X    long   qh_system;        /* total system CPU time for jobs in this queue */
  1369. X    long   qh_jobcount;        /* total no of jobs processed */
  1370. X    char   qh_spool[64];    /* spool file directory for this queue
  1371. X                       (default is /usr/spool) */
  1372. X    char   qh_defmon[64];       /* default monitor for queue 
  1373. X                   (default is <qh_spool>/<qname>.mon) */
  1374. X};
  1375. X    
  1376. struct queue_entry {
  1377. X    int    qe_jobno;            /* identifier for this job */
  1378. X    pid_t  qe_status;            /* flag set (to it's pid)  if this job is 
  1379. X                   running */
  1380. X    int    qe_repcount;         /* internal flag for environment */
  1381. X    int    qe_notify;           /* notification flag .. 0 = none */
  1382. X                                /* 1 = display message, 2 = mail */
  1383. X    uid_t  qe_uid;              /* uid of activity submitting this job */
  1384. X    gid_t  qe_gid;              /* gid of activity submitting this job */
  1385. X    time_t qe_submitted;    /* time this job was submitted */
  1386. X    char   qe_uname[16];        /* user name of submittor */
  1387. X    char   qe_tty[8];           /* user's terminal if interactive */
  1388. X    char   qe_jobname[32];    /* optional user job name */
  1389. X    char   qe_jcl[64];            /* filename of job file submitted */
  1390. X    char   qe_monitor[64];    /* monitor file for this job if not
  1391. X                   default */
  1392. X};
  1393. struct queue_header head;
  1394. struct queue_entry entry;
  1395. void qb_term();
  1396. void qb_exit();
  1397. void tell_qp();
  1398. void q_lock();
  1399. void q_unlock();
  1400. void qb_setterm(); void handle_flags();
  1401. void qb_setgrp();
  1402. void kill_child_group();
  1403. void toggle_halt_status();
  1404. END_OF_FILE
  1405. if test 3583 -ne `wc -c <'src/qbatch.h'`; then
  1406.     echo shar: \"'src/qbatch.h'\" unpacked with wrong size!
  1407. fi
  1408. # end of 'src/qbatch.h'
  1409. fi
  1410. if test -f 'src/qs.c' -a "${1}" != "-c" ; then 
  1411.   echo shar: Will not clobber existing file \"'src/qs.c'\"
  1412. else
  1413. echo shar: Extracting \"'src/qs.c'\" \(2998 characters\)
  1414. sed "s/^X//" >'src/qs.c' <<'END_OF_FILE'
  1415. X/************************************************************************/  
  1416. X/*                                                                      */
  1417. X/* qs .. queue stop. Set the stop flag for a given queue so that qp     */
  1418. X/*                   terminates when current job is finished.           */
  1419. X/*                   (optionally to kill or repeat and kill current job)*/
  1420. X/*                                                                      */
  1421. X/*      usage: qs [-k] [-r] [-w] qname                          */
  1422. X/*                                                                      */
  1423. X/*   Copyright (c) Vita Services 1990                                   */
  1424. X/*             (c) Vita Fibres   1990 1991                              */
  1425. X/*                                                                      */
  1426. X/************************************************************************/
  1427. X
  1428. X#include "qbatch.h"
  1429. X
  1430. int fpq = 0;
  1431. int kflag = 0, rflag = 0, wflag = 0;
  1432. char *queuename;
  1433. char queue[128];
  1434. char buff [128];                            
  1435. X#include "config.h"
  1436. X                            
  1437. void qwait()
  1438. X{
  1439. X    do
  1440. X    {
  1441. X        fpq = open (queue, O_RDWR);
  1442. X        q_lock(fpq);
  1443. X        read  (fpq, &head, sizeof(head));
  1444. X        q_unlock(fpq);
  1445. X        close (fpq);fpq = 0;
  1446. X        if (head.qh_pid == 0) break;
  1447. X        sleep (30);
  1448. X    }
  1449. X    while (head.qh_pid != 0);
  1450. X
  1451. X    exit (0);
  1452. X}
  1453. X
  1454. main (argc, argv, envp)
  1455. int argc;
  1456. char *argv[], *envp[];
  1457. X{
  1458. X    int c;
  1459. X    extern char *optarg;
  1460. X    extern int optind;
  1461. X    if (getuid() != 0)
  1462. X    {
  1463. X        fprintf (stderr, "Must be root to stop a queue\n");
  1464. X        exit (-1);
  1465. X    }
  1466. X    while ((c = getopt (argc, argv, "krwv")) != -1)
  1467. X    switch (c)
  1468. X    {
  1469. X        case 'k':   kflag = 1;
  1470. X                    break;
  1471. X        case 'r':   rflag = 1;
  1472. X                    kflag ++;
  1473. X                    break;
  1474. X        case 'w':   wflag = 1;
  1475. X                    break;
  1476. X        case 'v':   q_version();
  1477. X    }
  1478. X    if (optind >= argc)
  1479. X    {
  1480. X        fprintf(stderr, "Usage : qs <qname>\n");
  1481. X        exit (-1);
  1482. X    }
  1483. X    queuename = argv[optind];
  1484. X    strcpy (queue, QUEUEPATH);
  1485. X    strcat (queue, queuename);
  1486. X    qb_setterm();
  1487. X    fpq = open (queue, O_RDWR);
  1488. X    q_lock(fpq);
  1489. X    read  (fpq, &head, sizeof(head));
  1490. X    if (bad_queue()) qb_exit(-1);
  1491. X    if (head.qh_noentries > 0) read  (fpq, &entry, sizeof(entry));
  1492. X    if ((head.qh_flags & qh_stop) > 0)
  1493. X    {
  1494. X        if (wflag == 0)
  1495. X        {
  1496. X            fprintf (stderr, "Queue %s is already stopped!\n", queue);
  1497. X            qb_exit(-1);
  1498. X        }
  1499. X        else qwait();    
  1500. X    }
  1501. X    head.qh_flags ^= qh_stop;
  1502. X    if (rflag)
  1503. X    {
  1504. X        if ((head.qh_flags&qh_repeat) == 0) 
  1505. X        {
  1506. X            head.qh_flags += qh_repeat;
  1507. X        }
  1508. X    }
  1509. X    if (rflag || kflag)
  1510. X    {
  1511. X        if ((head.qh_flags&qh_kill) == 0) 
  1512. X        {
  1513. X            head.qh_flags += qh_kill;
  1514. X        }
  1515. X    }
  1516. X    lseek (fpq, 0, SEEK_SET);
  1517. X    write (fpq, &head, sizeof(head));
  1518. X    q_unlock(fpq);
  1519. X    close (fpq);fpq = 0;
  1520. X    tell_qp();
  1521. X    if (wflag != 0) qwait();
  1522. X    qb_term (0);
  1523. X}
  1524. END_OF_FILE
  1525. if test 2998 -ne `wc -c <'src/qs.c'`; then
  1526.     echo shar: \"'src/qs.c'\" unpacked with wrong size!
  1527. fi
  1528. # end of 'src/qs.c'
  1529. fi
  1530. if test -f 'src/qt.c' -a "${1}" != "-c" ; then 
  1531.   echo shar: Will not clobber existing file \"'src/qt.c'\"
  1532. else
  1533. echo shar: Extracting \"'src/qt.c'\" \(4128 characters\)
  1534. sed "s/^X//" >'src/qt.c' <<'END_OF_FILE'
  1535. X/************************************************************************/
  1536. X/*                                     */
  1537. X/* qf .. queue find. Report information about a queue                   */
  1538. X/*                                     */
  1539. X/*   Copyright (c) Vita Services 1990                                   */
  1540. X/*             (c) Vita Fibres   1990 1991                              */
  1541. X/*                                     */
  1542. X/************************************************************************/
  1543. X
  1544. X#include <stdlib.h>
  1545. X#include "qbatch.h"
  1546. char buff[128];
  1547. XFILE *fpq;
  1548. char *queuename;
  1549. char *fcptr;
  1550. char rcmd[128];
  1551. int qpuid[10];
  1552. int qpgid[10];
  1553. int permission, fixedcontext;
  1554. int jobuid, jobgid;
  1555. int i,j;
  1556. int c;
  1557. void q_version()
  1558. X{
  1559. X    puts (&QbSID[5]);
  1560. X    puts ("");
  1561. X    puts (&QbCR1[5]);
  1562. X    puts (&QbCR2[5]);
  1563. X    puts ("");
  1564. X    exit(0);
  1565. X}
  1566. int bad_queue()
  1567. X{
  1568. X    if (strcmp (head.q_magic, "qBq") != 0)
  1569. X    {
  1570. X        if (c != 'U') fprintf(stderr,"%s is not a valid QBATCH queue\007\n", queuename);
  1571. X        return(-1);
  1572. X    }
  1573. X    return(0);
  1574. X}
  1575. void usage()
  1576. X{
  1577. X    puts("Usage: qt -[e]|[f]|[h]|[k]|[r]|[s]|[u]|[t]|[v] <queuename>");
  1578. X    exit (0);
  1579. X}
  1580. void ext(flag)
  1581. int flag;
  1582. X{
  1583. X    exit ((flag == 0)?1:0);
  1584. X}
  1585. void do_list()
  1586. X{
  1587. X    printf("%-8s %6d     ", queuename, head.qh_noentries);
  1588. X    printf("%6d           ", head.qh_priority);
  1589. X    printf("%s      ",(head.qh_flags&qh_fixed)?"yes": "no ");
  1590. X    printf("%s     ",(head.qh_flags&qh_enabled)?"yes": "no ");
  1591. X    printf("%s     ",(head.qh_flags&qh_halt)?"yes": "no ");
  1592. X    printf("%s\n",   (head.qh_flags&qh_stop)?"yes": "no ");
  1593. X}
  1594. main (argc, argv)
  1595. int argc;
  1596. char *argv[];
  1597. X{
  1598. X    extern char *optarg;
  1599. X    extern int   optind;
  1600. X    if ((c = getopt (argc, argv, "efhklrstuv")) == -1) usage();
  1601. X    if (c == 'v') q_version();
  1602. X    if (optind >= argc)
  1603. X    {
  1604. X        fprintf (stderr, "Invalid or missing queue name!\n");
  1605. X        exit (-1);
  1606. X    }
  1607. X    queuename = argv[optind];
  1608. X    strcpy (buff, QUEUEPATH);
  1609. X    strcat (buff, queuename);
  1610. X    fpq = fopen (buff, "r");
  1611. X    if (fpq == NULL)
  1612. X    {
  1613. X        fprintf (stderr, "Invalid queue name: %s!\n",queuename);
  1614. X    fclose (fpq);
  1615. X        exit (-1);
  1616. X    }
  1617. X    fread (&head, sizeof(head), 1, fpq);
  1618. X    if (bad_queue())
  1619. X    {
  1620. X    fclose (fpq);
  1621. X    exit (-1);
  1622. X    }
  1623. X    fclose (fpq);
  1624. X    switch (c)
  1625. X    {
  1626. X    case 't':    exit (0);
  1627. X    case 'e':    ext (head.qh_flags & qh_enabled);
  1628. X    case 'f':    ext (head.qh_flags & qh_fixed);
  1629. X    case 'h':    ext (head.qh_flags & qh_halt);
  1630. X    case 'k':    ext (head.qh_flags & qh_kill);
  1631. X    case 'r':    ext (head.qh_flags & qh_repeat);
  1632. X    case 's':    ext (head.qh_flags & qh_stop);
  1633. X    }
  1634. X    /* done the rest, must be -u  or -l*/
  1635. X    if ((head.qh_flags & qh_fixed) == 0)
  1636. X    {
  1637. X    /* not fixed context, anyone can use */
  1638. X    if (c == 'l') do_list();
  1639. X    exit (0);
  1640. X    }
  1641. X    strcpy (buff, QUEUEPATH);
  1642. X    strcat (buff, ".");
  1643. X    strcat (buff, queuename);
  1644. X    strcat (buff, "rc");
  1645. X    fpq = fopen (buff, "r");
  1646. X    if (fpq == NULL)
  1647. X    {
  1648. X    printf ("Can't access initialisation file: %s\n", buff);
  1649. X    fclose (fpq);
  1650. X    exit (-1);
  1651. X    }
  1652. X    jobuid = getuid();
  1653. X    jobgid = getgid();
  1654. X    fgets (buff, 128, fpq);
  1655. X    permission = 0;
  1656. X    fixedcontext = 0;
  1657. X    while (*buff != 0)  
  1658. X    {
  1659. X    sscanf (buff, "%s", rcmd);
  1660. X    if (strcmp (rcmd, "#QUSERS") == 0)
  1661. X    {
  1662. X         fixedcontext = 1;
  1663. X         if (permission > 0) break;
  1664. X         permission = 0;
  1665. X         /* check uid against list of permitted id's */
  1666. X         i = sscanf (buff,"%s%d%d%d%d%d%d%d%d%d%d", rcmd,
  1667. X              &qpuid[0],&qpuid[1],&qpuid[2],&qpuid[3], 
  1668. X              &qpuid[4],&qpuid[5],&qpuid[6],&qpuid[7],
  1669. X              &qpuid[8],&qpuid[9]);
  1670. X         for (j=0; j < i; j++)
  1671. X         if (qpuid[j] == jobuid) 
  1672. X         {
  1673. X          permission ++;     
  1674. X          break;
  1675. X         }
  1676. X    }
  1677. X    if (strcmp (rcmd, "#QGROUPS") == 0)
  1678. X    {
  1679. X         fixedcontext = 1;
  1680. X         if (permission > 0) break;
  1681. X         permission = 0;
  1682. X         /* check gid against list of permitted id's */
  1683. X         i = sscanf (buff,"%s%d%d%d%d%d%d%d%d%d%d", rcmd,
  1684. X              &qpgid[0],&qpgid[1],&qpgid[2],&qpgid[3], 
  1685. X              &qpgid[4],&qpgid[5],&qpgid[6],&qpgid[7],
  1686. X              &qpgid[8],&qpgid[9]);
  1687. X         for (j=0; j < i; j++)
  1688. X         if (qpgid[j] == jobgid) 
  1689. X         {
  1690. X          permission ++;     
  1691. X          break;
  1692. X         }
  1693. X    }
  1694. X    *buff = 0;
  1695. X    fgets (buff, 128, fpq);  
  1696. X    }
  1697. X    fclose(fpq);
  1698. X    if ((permission == 0) && (jobuid != 0) && (fixedcontext == 1)) exit (-1);
  1699. X    if (c == 'l') do_list();
  1700. X    exit(0);
  1701. X}
  1702. END_OF_FILE
  1703. if test 4128 -ne `wc -c <'src/qt.c'`; then
  1704.     echo shar: \"'src/qt.c'\" unpacked with wrong size!
  1705. fi
  1706. # end of 'src/qt.c'
  1707. fi
  1708. if test -f 'src/time.c' -a "${1}" != "-c" ; then 
  1709.   echo shar: Will not clobber existing file \"'src/time.c'\"
  1710. else
  1711. echo shar: Extracting \"'src/time.c'\" \(2608 characters\)
  1712. sed "s/^X//" >'src/time.c' <<'END_OF_FILE'
  1713. X/************************************************************************/  
  1714. X/*                                                                      */
  1715. X/* time.c Profile timing functions                                      */
  1716. X/*                                                                      */
  1717. X/*   Copyright (c) Vita Services 1990                                   */
  1718. X/*             (c) Vita Fibres   1990 1991                              */
  1719. X/*                                                                      */
  1720. X/************************************************************************/
  1721. X/*********************************************************************
  1722. X*
  1723. X* The purpose of this module is to provide some profiling and user
  1724. X* accounting facilities to QBATCH.  The time values as stored are in
  1725. X* resolutions of 1/100 secs.  The clock resolution on your system may
  1726. X* (probably will) not be this accurate.  For user and system times,
  1727. X* the times function returns the total time in clock ticks (the highest
  1728. X* resolution) into a struct tms. On SYSV systems, the return value is
  1729. X* a useful timebase also (in clock ticks). Other (BSD?) systems simply
  1730. X* return zero to imply success.  In these cases, you will have to find
  1731. X* some other way to find out the real time in 1/100 secs, or put up 
  1732. X* with using time(), and do without the fractions.
  1733. X*
  1734. X* Two functions are defined in this module:
  1735. X*
  1736. X* qb_start_timer():    Initialise variables so that the base values
  1737. X*            of the intervals is known.
  1738. X*
  1739. X* qb_get_timer():    calculate the intervals in 1/100 secs from the
  1740. X*            base values previously set.
  1741. X*
  1742. X* Three values (intervals) are to be maintained:
  1743. X* (all 1/100 sec resolution)
  1744. X*
  1745. X* The 'real' time  (i.e. clock time)
  1746. X*
  1747. X* CPU usage for user instructions for child processes.
  1748. X*
  1749. X* CPU usage for system execution for child processes.
  1750. X*
  1751. X* IMPORTANT These functions work together. Results are indeterminate
  1752. X* if they are not called in order.
  1753. X*
  1754. X*********************************************************************/
  1755. X#include <unistd.h>
  1756. X#include <sys/types.h>
  1757. X#include <sys/times.h>
  1758. X#include "config.h"
  1759. struct tms start_times, end_times;
  1760. clock_t real_start, real_end;
  1761. int clock_tick = 0;
  1762. void qb_set_timer()
  1763. X{
  1764. X    if (!clock_tick) clock_tick = QCLOCK_TICK;
  1765. X    real_start = times (&start_times);
  1766. X}
  1767. void qb_get_timer(real, user, system)
  1768. unsigned long *real, *user, *system;
  1769. X{
  1770. X    real_end = times(&end_times);
  1771. X    *real   = ((real_end - real_start) *100) / clock_tick;
  1772. X    *user   = ((end_times.tms_cutime - start_times.tms_cutime) *100) / clock_tick;
  1773. X    *system = ((end_times.tms_cstime - start_times.tms_cstime) *100) / clock_tick;
  1774. X}
  1775. END_OF_FILE
  1776. if test 2608 -ne `wc -c <'src/time.c'`; then
  1777.     echo shar: \"'src/time.c'\" unpacked with wrong size!
  1778. fi
  1779. # end of 'src/time.c'
  1780. fi
  1781. echo shar: End of archive 2 \(of 6\).
  1782. cp /dev/null ark2isdone
  1783. MISSING=""
  1784. for I in 1 2 3 4 5 6 ; do
  1785.     if test ! -f ark${I}isdone ; then
  1786.     MISSING="${MISSING} ${I}"
  1787.     fi
  1788. done
  1789. if test "${MISSING}" = "" ; then
  1790.     echo You have unpacked all 6 archives.
  1791.     rm -f ark[1-9]isdone
  1792. else
  1793.     echo You still need to unpack the following archives:
  1794.     echo "        " ${MISSING}
  1795. fi
  1796. ##  End of shell archive.
  1797. exit 0
  1798.  
  1799. exit 0 # Just in case...
  1800. -- 
  1801. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1802. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1803. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1804. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1805.